package com.mrq.qicamera;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.TextureView;
import android.view.WindowManager;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private TextureView mTextureView;
    private Camera mCamera;
    private int mWidth;
    private int mHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getPermission();

        DisplayMetrics dm = getResources().getDisplayMetrics();
        mHeight = dm.heightPixels;
        mWidth = dm.widthPixels;
        Log.d("jyq", "width =" + mWidth + "height = " + mHeight);
        initView();

    }

    private void getPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ArrayList<String> permissions = new ArrayList<>();
            if (!checkPermission(Manifest.permission.CAMERA)) {
                permissions.add(Manifest.permission.CAMERA);
            }
            if (!checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            if (permissions.size() > 0) {
                requestPermissions(permissions.toArray(new String[permissions.size()]), 1);
            }
        }
    }

    public boolean checkPermission(String perName) {
        if (TextUtils.isEmpty(perName)) {
            return true;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(perName) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    private void initView() {
        mTextureView = findViewById(R.id.texture_view_camera);

        mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
                openCamera(surfaceTexture);
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
                closeCamera();
                return true;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

            }
        });

    }

    private void closeCamera() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
        }
    }

    private void openCamera(SurfaceTexture surfaceTexture) {
        try {
            int numberOfCameras = Camera.getNumberOfCameras();
            mCamera = Camera.open(numberOfCameras - 1);
            mCamera.setPreviewTexture(surfaceTexture);
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            Camera.Parameters parameters = mCamera.getParameters();
            if (parameters != null) {
                parameters.setPreviewSize(1920, 1080);
                mCamera.setParameters(parameters);
            }
            int orientation = getOrientation(this);
            Log.d("jyq", "openCamera() orientation [" + orientation + "]");
            mCamera.setDisplayOrientation(orientation);
//            setCameraDisplayOrientation(0, mCamera);
            mCamera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取camera oritation
     *
     * @param context
     * @return
     */
    public static int getOrientation(Context context) {
        Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        int rotation = display.getRotation();
        int orientation;
        boolean expectPortrait;
        switch (rotation) {
            case Surface.ROTATION_0:
            default:
                Log.d("jyq", "getOrientation() rotation = [" + 0 + "]");
                orientation = 90;
                expectPortrait = true;
                break;
            case Surface.ROTATION_90:
                Log.d("jyq", "getOrientation() rotation = [" + 90 + "]");
                orientation = 0;
                expectPortrait = false;
                break;
            case Surface.ROTATION_180:
                Log.d("jyq", "getOrientation() rotation = [" + 180 + "]");
                orientation = 270;
                expectPortrait = true;
                break;
            case Surface.ROTATION_270:
                Log.d("jyq", "getOrientation() rotation = [" + 270 + "]");
                orientation = 180;
                expectPortrait = false;
                break;
        }
        boolean isPortrait = display.getHeight() > display.getWidth();
        if (isPortrait != expectPortrait) {
            orientation = (orientation + 270) % 360;
        }
        return orientation;
    }


    /**
     * google 获取camera  oritation
     *
     * @param cameraId
     * @param camera
     */
    public void setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        // 记录本机子相机的旋转角度
        camera.setDisplayOrientation(result);
    }

}
